package com.shine.filter;

import com.shine.constant.GatewayConstant;
import com.shine.context.SecurityContext;
import com.shine.context.SecurityContextHolder;
import com.shine.entity.User;
import com.shine.exception.BaseException;
import com.shine.properties.GatewayCustomizeProperties;
import com.shine.constant.SecurityConstant;
import com.shine.security.Principal;
import com.shine.security.UserPrincipal;
import com.shine.status.ResponseStatus;
import com.shine.token.TokenManager;
import com.shine.utils.PathMatchUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * Servlet 版本的 RemoveHeaderFilter
 */
@Slf4j
@Component
public class RemoveHeaderFilter extends BaseFilter implements Filter, Ordered {

    @Resource
    private GatewayCustomizeProperties gatewayCustomizeProperties;

    @Override
    public int getOrder() {
        return GatewayConstant.FILTER_ORDER_REMOVE_HEADER;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("RemoveHeaderFilter 初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String path = request.getRequestURI();
        String token = request.getHeader(SecurityConstant.HEADER_TOKEN_KEY);

        if (PathMatchUtil.match(gatewayCustomizeProperties.getAuthorizationExcludePath(), path)) {
            // 不需要验证的路径
            if (StringUtils.isNotBlank(token)) {
                token = token.replace("Bearer ", "");
                try {
                    TokenManager.parse(token); // 尝试解析
                } catch (Exception e) {
                    log.error("解析Token异常，但路径允许访问: {}", token);
                    // 解析失败，包装请求删除 token
                    HttpServletRequest wrappedRequest = new HttpServletRequestWrapper(request) {
                        @Override
                        public String getHeader(String name) {
                            if (SecurityConstant.HEADER_TOKEN_KEY.equalsIgnoreCase(name)) {
                                return null;
                            }
                            return super.getHeader(name);
                        }
                    };
                    chain.doFilter(wrappedRequest, response);
                    return; // 包装后直接返回
                }
            }
            // token 解析成功或为空，直接放行原 request
            chain.doFilter(request, response);
        } else {
            // 需要验证的路径
            if (StringUtils.isNotBlank(token)) {
                token = token.replace("Bearer ", "");
                try {
                    UserPrincipal user = TokenManager.parse(token);
                    SecurityContext<Principal> context = new SecurityContext<>();
                    context.setPrincipal(user);
                    SecurityContextHolder.setContext(context);
                } catch (Exception e) {
                    log.error("Token已过期：{}", token);
                    handleException(response, ResponseStatus.EXPIRED_TOKEN);
                    return;
                }
            } else {
                log.error("用户没有登录");
                handleException(response, ResponseStatus.NO_LOGIN);
                return;
            }
            // 必须验证路径，用原始 request
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {
        log.info("RemoveHeaderFilter 销毁");
        SecurityContextHolder.clearContext();
    }

}
